<?php
class ZeusLib_Resource_Xml_Collection extends ZeusLib_Resource_Collection
{

	/**
	 * Files to load
	 * 
	 * @var array
	 */
	private $_files;

	
	protected function _construct()
	{
		$this->_files = array();
	}

	/**
	 * Adds a file to the xml collection.
	 * 
	 * @param string $xmlFilePath
	 */
	public function addFile($xmlFilePath)
	{
		// Check whether the file not exists
		if(!in_array($xmlFilePath, $this->_files))
		{
			// Add the file
			$this->_files[] = $xmlFilePath;
		}
	}

	public function load()
	{
		// Iterate all xml files
		foreach($this->_files as $xmlFilePath)
		{
			// Get a parser instance
			$parser = new ZeusLib_Resource_Xml_Parser();

			// Load the xml file
			$parser->load($xmlFilePath);

			// Get the root element from the loaded document
			$rootElement = $parser->getRootElement();

			// Merge the data into this collection
			$this->merge($rootElement->getName(), $rootElement);
		}

		// Set loading was successful
		$this->setIsLoaded($this->dataChanged());
		
		// Reset the files array
		$this->_files = array();
	}
	
	/**
	 * Merge the collection into one element object structure
	 * 
	 * @param string $name
	 * @param ZeusLib_Resource_Xml_Collection_Element $element
	 */
	public function merge($name, $element)
	{
		// Check whether the data of the root element already exists
		if($this->hasData($name))
		{
			// Merge the elements
			$this->getData($name)->merge($element);
		}
		// The data does not exist
		else
		{
			// Add the data
			$this->setData($name, $element);
		}
	}

	/**
	 * Searches in the xml element structure for the slash separated
	 * nodes in the search string.
	 *
	 * E.g. find('config/...')
	 * within the config is a root element of the xml structure.
	 *
	 * If the node does not exist, null is returned.
	 *
	 * @param string $search
	 * @return ZeusLib_Resource_Xml_Collection_Element|null
	 */
	public function find($search)
	{
		// Get the position of the first slash
		$slashPos = strpos($search, '/');

		// Check whether a slash in the search string existed
		if($slashPos !== false)
		{
			// Set the requested name to the search string until the first slash
			$requestedName = substr($search, 0, $slashPos);
			
			// Set the next search string to the search begginning from the first slash
			$nextSearch = substr($search, $slashPos + 1);
		}
		// No slash in the search string
		else
		{
			// Set the requested name to this search
			$requestedName = $search;
			
			// Set the next search to null
			$nextSearch = null;
		}

		// Return the child if it exists, otherwise return null if the child cannot be found
		return $this->hasData($requestedName) ? $this->getData($requestedName)->find($nextSearch) : null;
	}
	
	/**
	 * Output the structure of the collection
	 */
	public function toString()
	{
		// Output cache
		$outputCache = array();

		// Iterate all elements
		foreach($this as $element)
		{
			// Output the element
			$outputCache[] = $element->toString();
		}

		// Return the output
		return implode("\n\n", $outputCache);
	}

}